import React, {PureComponent} from 'react';
import {Button, Col, Collapse, Form, Icon, message, Modal, Popconfirm, Row, Select, Spin} from "antd";
import {createChannelWithNodes, deleteChannel, getChannelListDetail, updateChannel} from "../../api/channel";
import {getCollectorList} from "../../api/collector";
import AddPage from "./AddPage";
import ConfigPage from "./ConfigPage";
import {createNode, deleteNode, updateBulkNodes, updateNode} from "../../api/node";
import {delSection, getSectionList} from "../../api/section";
import CronConfigPage from "./CronConfigPage";


const {Panel} = Collapse;

class Index extends PureComponent {
  sections = [];
  defaultChannel = {}
  defaultIndex = 0 //动态节点默认索引
  currentPanelIndex = 0; //当前面板索引
  currentModalType = 'add'

  // lines = []

  constructor(props) {
    super(props);

    this.state = {
      loading: true,
      channelVisible: false,
      showModal: false,
      closable: true,
      //动态添加节点时需要的当前索引
      currentIndex: 0,
      //采集器集合
      collectorList: [],
      channelList: [],
      channel: {
        name: "",
        nodes: []
      },
      channelType: 'video'
    }
  }


  componentDidMount = () => {
    this.getChannelListDetail().finally(() => this.setState({loading: false}));
    this.initModal();
  };

  componentWillUnmount() {
    // console.log('unmount')
    this._hideAllLines()
  }

  //初始化联线
  _initLines = (nodesMap) => {
    // console.log('initLine');
    Array.isArray(nodesMap) && nodesMap.map(node => {
      if (node.adjacency_nodes.length > 0) {
        const sNode = document.getElementById(node.node);
        node.adjacency_nodes.map(tId => {
          const tNode = document.getElementById(tId);
          if (sNode && tNode) {
            const line = new window.LeaderLine(sNode, tNode, {path: 'grid'});
            line.position();
            // debugger
            this.addLine(line)
          }
        })
      }
    })
  };

  //自定义图标 编辑
  _genExtra(index) {
    const sChannel = this.state.channelList[index];
    return (
      <div>
        {/*解锁图标*/}
        <Icon style={{fontSize: '15px'}} type={sChannel.locked ? 'lock' : 'unlock'} onClick={(event) => {
          event.stopPropagation()
          const {channelList} = this.state
          channelList.splice(index, 1, {...sChannel, locked: !sChannel.locked})
          this.setState({
            channelList: [
              ...channelList
            ]
          })
        }}/>
        {/*编辑*/}
        <a style={{padding: '5px', marginLeft: '20px'}} onClick={(event) => {
          event.stopPropagation();
          this.currentModalType = 'edit';
          const tChannel = {...this.state.channel, ...sChannel};
          tChannel.nodes = sChannel.nodes.map((sNode) => {
            return {
              ...sNode,
              level: sNode.level.toString(),
              collector: sNode.collector.url
            }
          });
          // debugger
          this.setState({
            channel: tChannel,
            showModal: true,
            closable: true
          });

        }}>编辑</a>
        <a style={{marginLeft: '20px'}} onClick={(event => {
          event.stopPropagation();
          this.currentPanelIndex = index;
          this.currentModalType = 'edit';
          this.setState({
            channelVisible: true
          })
        })}>删除</a>


      </div>
    )
  }

  //获取频道列表
  getChannelListDetail = async (value, type) => {
    //如果当前有打开的选项卡，则先将此选项卡的Lines保存在this对象中
    if (!type) {
      // this.currentPanelIndex = currentPanelIndex ? currentPanelIndex : 0
      if (this.currentPanelIndex) {
        this.lines = this.state?.channelList[this.currentPanelIndex]?.lines
      }
    }
    const res = await getChannelListDetail({type: value || this.state.channelType});
    //读取完数据后重新将this.lines挂载到对应的channelList[currentPageIndex]中
    if (!type && this.currentPanelIndex && res && res.results && res.results[this.currentPanelIndex]) {
      res.results[this.currentPanelIndex]["lines"] = this.lines
    }

    this.setState({
      // channelList: res.results
      channelList: res?.results?.map(channel => {
        return {
          ...channel,
          nodes: channel?.nodes?.map(node => ({
              ...node,
              name: node?.collector?.name
            })
          ),
          locked: true
        }
      })
    })
  };

  //获取监测点列表
  getCollectorList = async (channelType = "video") => {
    const collectorList = (await getCollectorList({type: channelType, pageSize: 1000})).results;
    this.setState((state) => {
      state.collectorList = collectorList
    })
  };

  //节点层级选择
  onLevelSelect = (value, options) => {
    const {nodeIndex, nodes, node} = this.getSelectNode(options);
    const newNode = {...node, level: value};
    nodes.splice(nodeIndex, 1, newNode);
    if (this.currentModalType == 'edit') {
      updateNode(newNode).then(() => {
        this.getChannelListDetail()
        message.info('节点层级修改成功!');
      })
    }
    //todo 需要修改
    this.setState({
      channel: {
        ...this.state.channel,
        nodes: [
          ...nodes
        ]
      }
    })
  };

  //动态添加的采集点选择事件,修改选择点的数据
  onCollectorSelect = (value, options) => {
    const {nodeIndex, nodes, node} = this.getSelectNode(options);
    const newNode = {...node, name: options.props.children, collector: value};
    if (this.currentModalType == 'edit') {
      updateNode(newNode).then(res => {
        this.getChannelListDetail().then(()=>{
          message.info('监测点修改成功!');
        })
      })
    }
    // debugger
    nodes.splice(nodeIndex, 1, newNode);
    //todo 需要修改
    this.setState({
      channel: {
        ...this.state.channel,
        nodes: [
          ...nodes
        ]
      }
    })
  };

  //获取选中的采集点
  getSelectNode(options) {
    // debugger
    const nodeIndex = options?.props['node-index'];
    const {nodes} = this.state.channel;
    const node = nodes[nodeIndex];
    return {nodeIndex, nodes, node};
  }


  //初始化模态框数据
  async initModal() {
    this.initChannel();
    await this.getCollectorList(this.state.channelType)
    // this.initNodes()
  }

  //初始化链路
  initChannel(channel_type = 'video') {
    this.defaultChannel = {
      name: "",
      channel_type: channel_type,
      nodes: []
    };
    this.setState((state, props) => {
      return {channel: this.defaultChannel}
    })
  }

  //动态添加节点
  onAddClick = async (callback) => {

    const {channel} = this.state;
    const {nodes} = channel;
    const createTempNode = () => {
      const node = {
        level: '1',
        collector: this.state.collectorList[0].url,
        x_axis: this.defaultIndex,
        y_axis: 0
      };
      return node
    }
    if (this.currentModalType == 'add') {
      const newNodes = [...nodes, createTempNode()];
      this.setState({
        channel: {
          ...channel, nodes: newNodes
        }
      })
      this.defaultIndex++;
    } else {
      const sortArr = nodes.map(node => node.x_axis).sort((preIndex, curIndex) => preIndex - curIndex)
      // console.log(111, sortArr)
      this.defaultIndex = 0;
      sortArr.map((nodeIndex, index) => {
        if (nodeIndex == this.defaultIndex) {
          this.defaultIndex++
        }
      })
      if (this.defaultIndex >= 40) {
        message.warn("节点太多，超出范围")
        return
      }
      const postNode = {
        ...createTempNode(),
        channel: channel.url
      };
      await createNode(postNode).then((res) => {
        const editNodes = [...nodes, {...res, level: res.level + ""}];
        this.setState({
          channel: {
            ...channel, nodes: editNodes
          }
        })
      })
      message.info('节点添加成功!');
      // callback && callback()
    }
    callback && callback()
  };

  //删除动态添加的节点
  onDeleteClick = async (index, callback) => {
    const {nodes} = this.state?.channel;
    const node = nodes.splice(index, 1)[0];
    if (this.currentModalType == 'edit') {
      await deleteNode(node.id);
      message.info('节点删除成功!');
      const currentChannel = this.currentPanelIndex && this.state?.channelList[this.currentPanelIndex]
      currentChannel && currentChannel.lines && currentChannel.lines.forEach((line, index) => {
        if (line.start.id == node.id || line.end.id == node.id) {
          currentChannel.lines.splice(index, 1)
          line.remove();
        }

      })
    }
    this.setState({channel: {...this.state?.channel, nodes: [...nodes]}})
    callback && callback()
  };
  //模态框取消
  onCancelClick = () => {
    console.log('cancle')
    this.onOkClick()
    this.setState({showModal: false})
    // this.initModal()
  };

  //模态框确认
  onOkClick = () => {
    this.setState({loading: true})
    this.props.form.validateFields({}, async (err, values) => {
      if (err) {
        return false
      } else {
        this.setState({
          showModal: false,
        });
        const {channel} = this.state;

        if (this.currentModalType == 'add') {
          const res = await createChannelWithNodes({
            ...channel,
            name: this.props.form.getFieldValue("channelName")
          })
          await this.getChannelListDetail()
        } else if (this.currentModalType == 'edit') {
          const res = await updateChannel({...channel, name: this.props.form.getFieldValue("channelName")})
          await this.getChannelListDetail()
        }
        this.setState({loading: false})
      }
    });

  };

  //链路名称输入
  onChannelChange = (e) => {
    // console.log(111, e.target.value);
    // console.log(this.props.form.getFieldsValue());

    this.props.form.setFields({
      channelName: {
        value: e.target.value
      }
    });
    this.setState({channel: {...this.state.channel, name: e.target.value}})
  };

  //更新频道列表中的节点
  updateNodes = (nodes) => {
    const channelList = this.state.channelList;
    const channel = {...channelList[this.currentPanelIndex], nodes: [...nodes]};
    channelList.splice(this.currentPanelIndex, 1, channel);
    this.setState({
      channelList: [...channelList]
    })
  };

  //删除链路
  _delChannel = async () => {
    this.setState({
      channelVisible: false,
      loading: true
    });
    const id = this.state.channelList[this.currentPanelIndex].id;
    await deleteChannel(id).then(async res => {
      if (!res) {
        await this.getChannelListDetail()
      }
    })
    this.setState({loading: false})
  };

  //频道类型下拉框
  _onChannelChange = async (value) => {
    this.removeAllLine()
    this.setState({
      loading: true,
      channelType: value,
      channel: {...this.state.channel, channel_type: value}
    });
    this.getChannelListDetail(value, 'change').then(() => {
      this.currentPanelIndex && this._showLines()
      this.setState({
        loading: false
      })
    });
    this.getCollectorList(value)
    // console.log(11, value)
  };

  //折叠面板打开关闭
  _onCollapseChange = (index) => {
    this._hideAllLines();
    this.currentPanelIndex = index;
    if (index) {
      const {id} = this.state.channelList[index];
      getSectionList(id).then(res => {
        this.sections = res.results
      });
      this._showLines()
    } else {
      this.setState({
        state: {}
      })
    }
  };

  //隐藏所有联线
  _hideAllLines = () => {
    this.state.channelList && this.state.channelList.map(channel => {
      channel.lines && channel.lines.map(line => {
        line.hide('none')
      })
    })
  };

  //显示当前打开折叠面板中的联线
  _showLines = () => {
    const channel = this.state.channelList[this.currentPanelIndex];
    // debugger
    if (channel?.lines) {
      channel.lines.map(line => {
        line.show()
      })
    } else {
      setTimeout(() => {
        this._initLines(channel.nodes_map)
      }, 350)
    }
  };

  //添加节点间的联线
  addLine = (line) => {
    const {channelList} = this.state;
    let channel = channelList[this.currentPanelIndex];
    // debugger
    if (Array.isArray(channel.lines) && line) {
      channel.lines.push(line)
    } else {
      channel = {...channel, lines: [line]};
      channelList.splice(this.currentPanelIndex, 1, channel);

    }
    this.setState({
      channelList: [...channelList]
    })
    getSectionList(channel.id).then(res => {
      this.sections = res.results
    })
  };

  _removeLine() {

  }

  //删除连线
  delLine = (channelIndex) => (lineIndex, sUrl, tUrl) => {
    const {channelList} = this.state;
    let channel = channelList[channelIndex];
    const lines = channel.lines;
    if (Array.isArray(channel.lines)) {
      const line = lines.splice(lineIndex, 1);

      this.sections.map(section => {
        const {sample_node, meta_node} = section;
        if (sample_node == sUrl && meta_node == tUrl || sample_node == tUrl && meta_node == sUrl) {
          delSection(section.id).then(() => {
            line[0].remove();
            channel = {...channel, lines: [...lines]};
            channelList.splice(channelIndex, 1, channel);
            this.setState({
              channelList: [...channelList]
            })
          });

        }
      })
    }
  };

  removeAllLine() {
    this.state.channelList && this.state.channelList.map(channel => {
      channel.lines && channel.lines.map((line) => {
        line.remove()
      })
    })
  }

  //新增比对链路
  _addChannel = () => {
    this.currentModalType = 'add';
    this.initChannel(this.state.channelType);
    this.setState({
      showModal: true
    })
  };

  render() {
    // console.log('render channelConfig');
    return (
      <>
        <Row type={"flex"}>
          <Col span={8}>
            链路类型：<Select value={this.state.channelType} style={{width: '150px'}}
                         onChange={this._onChannelChange}>
            <Select.Option value="video">电视链路</Select.Option>
            <Select.Option value="audio">广播链路</Select.Option>
          </Select>
          </Col>
          <Col span={4} offset={12}>
            <Button onClick={this._addChannel}>新增比对链路</Button>
          </Col>
        </Row>
        <Spin spinning={this.state.loading} size={'large'} tip={'数据加载中'}>
          <Collapse accordion style={{marginTop: '20px'}}
                    onChange={this._onCollapseChange}>
            {
              this.state?.channelList?.map((item, index) => {
                return (
                  <Panel header={item.name} key={index} extra={this._genExtra(index)}>
                    <div style={{
                      height: '400px',
                      position: 'relative',
                    }}>
                      <ConfigPage
                        canDrag={!item.locked}
                        nodes={item.nodes}
                        addLine={this.addLine}
                        delLine={this.delLine(index)}
                        lines={item.lines}
                        updateNodes={this.updateNodes}
                      />
                    </div>
                    <div style={{position: 'relative', marginTop: '10px'}}>
                      <CronConfigPage channelUrl={item.url} channelId={item.id}/>
                    </div>
                  </Panel>
                )
              })
            }
          </Collapse>
        </Spin>
        <Modal
          closable={this.state.closable}
          width={800}
          visible={this.state.showModal}
          onCancel={this.onCancelClick}
          maskClosable={this.state.closable}
          destroyOnClose
          okButtonProps={this.currentModalType == 'edit' && {style: {display: "none"}}}
          cancelButtonProps={this.currentModalType == 'edit' && {style: {display: "none"}}}
        >
          <AddPage
            onAddClick={this.onAddClick}
            onDeleteClick={this.onDeleteClick}
            onCollectorSelect={this.onCollectorSelect}
            onLevelSelect={this.onLevelSelect}
            onChannelChange={this.onChannelChange}
            channel={this.state.channel}
            collectorList={this.state.collectorList}
            form={this.props.form}
          />
        </Modal>
        <Modal
          title="提示"
          visible={this.state.channelVisible}
          onOk={this._delChannel}
          onCancel={() => {
            this.setState({
              channelVisible: false
            })
          }}
          okText="确认"
          cancelText="取消"
        >
          <p>确定删除当前链路吗?</p>
        </Modal>
      </>
    );
  }
}

const WrappedAddChanelForm = Form.create({name: 'addChannel'})(Index);
export default WrappedAddChanelForm;

